<template>
  <div class="card-full">
    <div class="search-box">
      <el-form ref="ruleSearchFormRef" class="search-form" :model="searchForm" inline>
        <el-form-item label="" prop="keyword">
          <el-input v-model="searchForm.keyword" placeholder="输入关键词搜索" />
        </el-form-item>
      </el-form>
      <el-button class="ml-4" type="primary" @click="getList">查询</el-button>
      <el-button plain @click="(ruleSearchFormRef.resetFields(), getList())">重置</el-button>
    </div>
    <div class="mb-2">
      <el-button v-permission="'menu:add'" type="primary" @click="isShow = true">新增</el-button>
    </div>
    <div class="table-box">
      <el-table :data="tableData" row-key="id" border header-align="center">
        <el-table-column prop="meta.title" label="菜单名称" min-width="150" align="left" />
        <el-table-column prop="meta.title" label="菜单类型" min-width="100" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.meta.type === 4" type="success">目录</el-tag>
            <el-tag v-else-if="scope.row.meta.type === 1" type="warning">菜单</el-tag>
            <el-tag v-else type="warning">按钮</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="meta.icon" label="菜单图标" width="90" align="center">
          <template #default="scope">
            <template v-if="scope.row.meta.icon || scope.row.meta.icon_svg">
              <SvgIcon v-if="scope.row.meta.icon_svg" :name="scope.row.meta.icon_svg" size="2rem" />
              <el-icon v-else>
                <component :is="scope.row.meta.icon" :id="scope.row.id"></component>
              </el-icon>
            </template>
          </template>
        </el-table-column>
        <el-table-column prop="path" label="路由路径" width="120" />
        <el-table-column prop="name" label="路由名称" width="120" />
        <el-table-column prop="component" label="组件路径" width="160" />
        <el-table-column prop="name" label="权限标识" width="100" align="center" />
        <el-table-column prop="sort" label="排序" align="center" />
        <el-table-column prop="meta.is_link" label="是否外链" width="100" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.meta.is_link === 1" type="success">是</el-tag>
            <el-tag v-else type="danger">否</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="meta.keep_alive" label="是否缓存" width="100" align="center">
          <template #default="scope">
            <el-tag :type="scope.row.meta.keep_alive ? 'primary' : 'danger'">
              {{ scope.row.meta.type ? "是" : "否" }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="meta.is_hidden" label="是否隐藏" width="100" align="center">
          <template #default="scope">
            <el-tag v-if="scope.row.meta.is_hidden === 1" type="success">是</el-tag>
            <el-tag v-else type="danger">否</el-tag>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" min-width="160" align="center">
          <template #default="scope">
            <el-button v-permission="'menu:update'" link type="primary" size="small" @click="handleClick(scope.row)"
              >编辑</el-button
            >
            <el-button v-permission="'menu:add'" link type="primary" size="small" @click="handleClick(scope.row, true)"
              >新增</el-button
            >
            <el-button v-permission="'menu:delete'" link type="primary" size="small" @click="handleDelete(scope.row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>
    <el-drawer v-model="isShow" size="36%" @close="resetForm">
      <template #header>
        <div class="font-bold">{{ form.id ? "编辑" : "新增" }}菜单</div>
      </template>
      <template #default>
        <div>
          <el-form ref="ruleFormRef" label-position="right" label-width="auto" :model="form" :rules="rules">
            <el-form-item label="菜单类型" prop="type">
              <el-radio-group v-model="form.type" aria-label="label position">
                <el-radio-button :value="4">目录</el-radio-button>
                <el-radio-button :value="1">菜单</el-radio-button>
                <el-radio-button :value="3">按钮</el-radio-button>
              </el-radio-group>
            </el-form-item>
            <el-form-item label="所属菜单" prop="pid">
              <el-tree-select v-model="form.pid" :data="treeSelectData" node-key="id" check-strictly> </el-tree-select>
            </el-form-item>
            <el-form-item v-if="form.type !== 3" label="菜单图标" prop="icon">
              <SelectIcon :model-value="form.icon" :clearable="true" @update:model-value="form.icon = $event" />
            </el-form-item>
            <el-form-item v-if="form.type !== 3" label="自定义图标" prop="icon_svg">
              <SelectIcon :model-value="form.icon_svg" :icon-type="'svg'" @update:model-value="form.icon_svg = $event" />
              <el-text class="mx-1" type="info" size="small">优先级高于菜单图标</el-text>
            </el-form-item>
            <el-form-item label="菜单标题" prop="title" required>
              <el-input v-model="form.title" placeholder="请输入菜单标题" />
            </el-form-item>
            <el-form-item v-if="form.type == 3" label="权限标识" prop="component" required>
              <el-input v-model="form.component" placeholder="请输入权限标识" />
            </el-form-item>
            <el-form-item v-if="form.type == 3" label="Api路径" prop="path" required>
              <el-input v-model="form.path" placeholder="请输入Api路径" />
            </el-form-item>
            <template v-if="form.type !== 3">
              <el-form-item label="路由名称" prop="name" required>
                <el-input v-model="form.name" placeholder="请输入路由名称" />
              </el-form-item>
              <el-form-item label="路由路径" prop="path" required>
                <el-input v-model="form.path" placeholder="请输入路由路径" />
              </el-form-item>
              <el-form-item v-if="form.type == 1" label="组件路径" prop="component">
                <el-input v-model="form.component" placeholder="请输入组件路径">
                  <template #prepend>@/view</template>
                  <template #append>.vue</template>
                </el-input>
              </el-form-item>
              <el-form-item label="菜单排序" prop="sort">
                <el-input-number v-model="form.sort" :min="1" />
              </el-form-item>
              <el-row :gutter="24" class="row-bg">
                <el-col :span="12">
                  <el-form-item label="是否隐藏" prop="is_hidden">
                    <el-switch v-model="form.is_hidden" :active-value="1" :inactive-value="2" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item label="是否启用" prop="status">
                    <el-switch v-model="form.status" :active-value="1" :inactive-value="2" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item v-if="form.type == 1" label="是否外链" prop="isLink">
                    <el-switch v-model="isLink" />
                  </el-form-item>
                </el-col>
                <el-col :span="12">
                  <el-form-item v-if="form.type == 1" label="是否缓存" prop="is_keep_alive">
                    <el-switch v-model="form.is_keep_alive" :active-value="1" :inactive-value="2" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-form-item v-if="isLink" label="外链地址" prop="link">
                <el-input v-model="form.link" placeholder="请输入外链地址" />
              </el-form-item>
            </template>
          </el-form>
        </div>
      </template>
      <template #footer>
        <div style="flex: auto">
          <el-button @click="resetForm">取消</el-button>
          <el-button type="primary" @click="confirmClick(ruleFormRef)">确定</el-button>
        </div>
      </template>
    </el-drawer>
  </div>
</template>
<script setup lang="ts">
// import * as Icons from "@element-plus/icons-vue";
import { ElForm, ElMessage } from "element-plus";
import * as Api from "@/api/modules/menu";
import type { FormInstance, FormRules } from "element-plus";

const searchForm = ref({ keyword: "" });
const ruleSearchFormRef = ref<FormInstance>();
const tableData = ref([]);
const getList = () => {
  Api.getMenuList(searchForm.value).then(res => {
    tableData.value = res.data.list;
  });
};
// 树选择器label不支持嵌套, 需要自定义label
const treeSelectData = computed(() => {
  const addLabel = nodes =>
    nodes.map(node => ({
      ...node,
      label: node.meta?.title ?? "",
      children: node.children ? addLabel(node.children) : []
    }));
  return addLabel([{ id: 0, pid: 0, meta: { title: "根菜单" }, children: tableData.value }]);
});

const isShow = ref(false);
const isLink = ref(false);
const form = ref<Api.Menu>({
  pid: 0,
  type: 4,
  sort: 1,
  status: 1,
  is_hidden: 2
});
const ruleFormRef = ref<FormInstance>();
const rules = reactive<FormRules<Api.Menu>>({
  title: { required: true, message: "请输入菜单标题", trigger: "blur" },
  name: { required: true, message: "请输入路由名称", trigger: "blur" },
  path: { required: true, message: "请输入路径", trigger: "blur" },
  component: { required: true, message: "请输入", trigger: "blur" }
});

const confirmClick = async (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  await formEl.validate(async (valid, fields) => {
    if (valid) {
      if (form.value.id) {
        await Api.editMenu(form.value).then(res => {
          getList();
          isShow.value = false;
        });
      } else {
        form.value.pid = form.value.pid ?? 0;
        await Api.addMenu(form.value).then(res => {
          getList();
          isShow.value = false;
        });
      }
      ElMessage({
        message: form.value.id ? "编辑成功" : "添加成功",
        type: "success"
      });
      resetForm();
    }
  });
};
const handleClick = (row, isAdd?: boolean) => {
  if (isAdd) {
    form.value.pid = row.id;
  } else {
    form.value = { ...row, ...row.meta };
  }
  isShow.value = true;
};
const handleDelete = (id: number) => {
  Api.delMenu({ ids: [id] })
    .then(res => {
      ElMessage({
        message: "删除成功",
        type: "success"
      });
      getList();
      isShow.value = false;
    })
    .catch(err => {
      ElMessage({
        message: err.message,
        type: "success"
      });
    });
};
const resetForm = () => {
  form.value = {
    pid: 0,
    type: 4,
    sort: 1,
    status: 1,
    is_hidden: 2
  };
  isLink.value = false;
  isShow.value = false;
};

onMounted(() => {
  getList();
});
</script>
<style lang="scss" scoped>
:deep(.el-drawer__footer) {
  padding: 15px;
  border-top: 1px solid var(--color-border-2);
}
:deep(.el-drawer__header) {
  margin-bottom: 0;
}
</style>
